//+--------------------------------------------------------------------
//| Copyright(c) 2012 - an.vuongngocduy					
//| This file is a part of Compact Game Engine (CGE)	
//+--------------------------------------------------------------------
#ifndef __CGE_STREAM_H__
#define __CGE_STREAM_H__

#include "cgeCommons.h"
#include "cgeProperty.h"

namespace cge
{
	namespace io
	{
		/// Base class of data stream
		class Stream
		{
		public:
			/// Default constructor.
			Stream()
			{
				/* Do nothing */
			}

			/// Destructor.
			~Stream()
			{
				/* Do nothing */
			}

			/// Return size of in byte of stream.
			u32 Size() const
			{
				return this->size();
			}
			
			/// Return position of IO operation in stream.
			u32 Position() const
			{
				return this->position();
			}

			/// Close stream and release resources held by stream.
			b8 Finalize()
			{
				return this->finalize();
			}

			/// Read number of bytes from current stream.
			u32 Read(u8* dst, u32 count)
			{
				return this->read(dst, count);
			}

			/// Write number of bytes into current stream.
			u32 Write(u8* src, u32 count)
			{
				return this->write(src, count);
			}

			/// Set the position for IO operation within the current stream.
			b8 Seek(u32 offset, b8 fromBeginning = false)
			{
				return this->seek(offset, fromBeginning);
			}

			/// Extract formatted data from stream
			template<class TArg>
			Stream& operator >> (TArg& dst)
			{
				this->read((u8*)&dst, sizeof(TArg));
			}

			/// Insert format data into stream
			template<class TArg>
			Stream& operator << (TArg& src)
			{
				this->write((u8*)&src, sizeof(TArg));
			}

		protected:
			/// Core of Finalize(). Must be defined by child class.
			virtual b8 finalize() = 0;

			/// Core of Size(). Must be defined by child class.
			virtual u32 size() const  = 0;
			
			/// Core of Position(). Must be defined by child class.
			virtual u32 position() const = 0;

			/// Core of Read(). Must be defined by child class.
			virtual u32 read(u8* dst, u32 count) = 0; 
			
			/// Core of Write(). Must be defined by child class.
			virtual u32 write(u8* src, u32 count) = 0;
	
			/// Core of Seek(). Must be defined by child class.
			virtual b8 seek(u32 offset, b8 fromBeginning)  = 0;
		};
	}
}

#endif//__CGE_STREAM_H__